Get multiple domains working again
authordjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Tue, 20 Sep 2005 19:03:25 +0000 (13:03 -0600)
committerdjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Tue, 20 Sep 2005 19:03:25 +0000 (13:03 -0600)
Signed-off-by Kevin Tian <kevin.tian@intel.com>

Some interesting issues found related to two small patches:
1. Only "xm console 1" and "Ctrl + ]" can make xenU forward progress,
and however still failed to connect blkback later.
[Reason] Previous event injection on XEN/IPF only set vIRR bit
when evtchn_set_pending. However with the latest xenlinux code, it's
possible for xenlinux to set pending indication and selector when
unmasking some pending event channel. This path has nothing to do with
vIRR bit.

[Solution] We should check event pending every time when
checking pending interrupts before returning to guest.

2. After fixing first issue, nested event is injected when first event
is still in handle with lock held. Then dead lock happens at end of
"xend start".
[Reason] Due to same logic as above, xenlinux may set pending
indication and re-trigger pending event by force_evtchn_callback. On
x86, this stub just does a dummy xen_version hypercall and pending event
will be injected back when leaving hypervisor. However on IA64,
force_evtchn_callback is incautiously made invoking evtchn_interrupt()
directly, while the former may be called with lock held.

[Solution] Just let force_evtchn_callback as empty for simple now.

xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/vcpu.c

index f1bf1f3791dc7f986229b5460865976e0df7c0aa..97b63af658f26a0d25a5232a9a90f58529960efb 100644 (file)
@@ -917,7 +917,7 @@ int construct_dom0(struct domain *d,
 #endif
 
        /* Mask all upcalls... */
-       for ( i = 0; i < MAX_VIRT_CPUS; i++ )
+       for ( i = 1; i < MAX_VIRT_CPUS; i++ )
            d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
 
 #ifdef CONFIG_VTI
index ec3c86e483b4469c62ab91997bcae83b4ddec41e..d650301242e94beb834badd046d8e98382f087ef 100644 (file)
@@ -21,6 +21,7 @@ int in_tpa = 0;
 #include <asm/processor.h>
 #include <asm/delay.h>
 #include <asm/vmx_vcpu.h>
+#include <xen/event.h>
 
 typedef        union {
        struct ia64_psr ia64_psr;
@@ -654,6 +655,15 @@ UINT64 vcpu_check_pending_interrupts(VCPU *vcpu)
 {
        UINT64 *p, *q, *r, bits, bitnum, mask, i, vector;
 
+       /* Always check pending event, since guest may just ack the
+        * event injection without handle. Later guest may throw out
+        * the event itself.
+        */
+       if (event_pending(vcpu) && 
+               !test_bit(vcpu->vcpu_info->arch.evtchn_vector,
+                       &PSCBX(vcpu, insvc[0])))
+               vcpu_pend_interrupt(vcpu, vcpu->vcpu_info->arch.evtchn_vector);
+
        p = &PSCBX(vcpu,irr[3]);
        /* q = &PSCB(vcpu,delivery_mask[3]); */
        r = &PSCBX(vcpu,insvc[3]);